/*
 * @Description: 自定义点 类型 1-精确着火点 2-粗略着火点 3-警察位置 4-消防员位置 5-漫游基站位置 6-风向标 300-空地协同固定翼 301-空地协同旋翼 302-地面站 400-转台
 * @Date: 2022-03-31 18:40:44
 * @Author: yeming
 */
import OlOverlay from 'ol/Overlay'
import { elementStr2Node, setAirGroundCooIconSvg } from '../common/svg.js'
import { fromLonLat } from 'ol/proj.js'
import { Point, Point3d } from '../model/point.js'
import { Line, Line3d } from '../model/line/line.js'
import { Circle, Circle3d } from '../model/circle.js'
import { removeFeatureAndDeleteHashMap, removeAllFeatureAndDeleteHashMap } from '../common/removeFeature.js'

import CustomOverlay from '../model/overlay.js'
import TrackLine from '../model/line/trackLine.js'

// 默认蓝色
const DEFAULT_CIRCLE_STYLE = { 'fillColor': 'rgba(0, 153, 255, 0.1)', 'strokeColor': 'rgba(0, 153, 255, 1)', 'strokeWidth': 2 }

const CSS_TEXT = 'width:100px;color: #fff;border-radius: 4px;padding: 5px 10px;box-sizing: border-box;font-size: 12px;text-align:center;'

class CustomPoint {
  constructor(ol2d, ol3d, pointHashMap, circleHashMap, vectorSource) {
    this.ol2d = ol2d
    this.ol3d = ol3d
    this.map2d = ol2d.map2d
    this.entities = ol3d.entities
    this.pointHashMap = pointHashMap
    this.circleHashMap = circleHashMap
    this.vectorSource = vectorSource

    this.trackLineMap = new Map() // 轨迹线
    this.overlayHashMap = new Map() // overlay
    this.clampToGroundLineHashMap = new Map() // 接地线
    this.popupOverlayInstance = new CustomOverlay(this.ol2d, this.overlayHashMap)
    this.trackLineInstance = new TrackLine(this.ol2d, this.ol3d, this.trackLineMap, this.vectorSource)
  }

  /**
   * @desc: 添加自定义点
   * @param {Number} sessionId
   * @param {Array} latlng
   * @param {Number} type 自定义点类型 1-精确着火点 2-粗略着火点 3-警察位置 4-消防员位置 5-漫游基站位置 6-风向标 300-空地协同固定翼 301-空地协同旋翼 302-pad 400-转台
   * @param {String} image
   * @param {Number} radius
   * @param {Number} isEdit
   * @param {Object} style
   * @param {Boolean} showOverlay 是否显示顶部label和接地线
   * @param {String} popupData 顶部label内容 eg：消防员-张三
   */
  addCustomPoint (sessionId, latlng, type, image, radius, isEdit, style, showOverlay, popupData, offset) {
    style = style && style != null ? style : DEFAULT_CIRCLE_STYLE

    if (type <= 6) {
      let point = new Point(this.ol2d, this.vectorSource)
      point.addCustomPoint(sessionId, latlng, type, image, radius, isEdit)

      let clampToGround = true
      if (type == 3 || type == 4) clampToGround = false

      let position = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2])
      let point3d = new Point3d(this.entities, 'customPoint3d_' + sessionId, type, 'rgba(0, 153, 255, 1)', '', image, clampToGround)
      point3d.position = position
      this.pointHashMap.set(sessionId, { 'item2d': point, 'item3d': point3d })

      // 3d circle 因为没有高度无法贴地，需要传入高度
      // 漫游基站添加circle
      if (radius > 0 && type == 5) this.addCustomPointCircle(sessionId, latlng, radius, style, false)
    }

    // 空地协同机组（固定翼、旋翼、pad，均属于overlay）
    if (type >= 300 && type <= 302) {
      let popupData = setAirGroundCooIconSvg(sessionId, type, style)
      this.popupOverlayInstance.addPopupOverlay('airGroundCoo_' + sessionId, latlng, popupData, '', [0, 23])
    }

    // 是否添加描述性overlay或者接地的线
    if (showOverlay) {
      let _latlng = [...latlng]
      _latlng[2] = latlng[2] + 500

      offset = offset && offset != '' ? offset : [0, -50]
      let cssText = CSS_TEXT + 'background:' + style.fillColor
      this.popupOverlayInstance.addPopupOverlay('label_' + sessionId, _latlng, popupData, cssText, offset)
      if (type == 4) this.addClampToGroundLine(sessionId, latlng, _latlng, style)
    }
  }

  /**
   * @desc: 修改自定义点
   * @param {Number} sessionId
   * @param {Array} latlng
   * @param {Number} type
   * @param {String} image
   * @param {Number} radius
   * @param {Object} style
   * @param {Boolean} showOverlay 是否显示顶部label和接地线
   * @param {String} popupData 顶部label内容 eg：消防员-张三
   * @param {Boolean} showTrack 是否显示航迹 eg：消防员轨迹线
   * @return {*}
   * @use: 使用示例
   */
  updateCustomPoint (sessionId, latlng, radius, style, showOverlay = true, popupData, showTrack) {
    let currentPoint = this.pointHashMap.get(sessionId).item2d
    // 2d点
    let coordinate = fromLonLat(latlng)
    let feature = currentPoint.feature
    if (feature != null) feature.getGeometry().setCoordinates(coordinate)
    // 3d点
    let currentPoint3d = this.pointHashMap.get(sessionId).item3d
    if (currentPoint3d) currentPoint3d.position = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2])

    // 更新circle
    if (radius > 0) this.updateCustomPointCircle(sessionId, latlng, radius, style)

    if (showTrack) {
      let type = feature.getProperties()['customType']
      if (type != 4) return false
      this.trackLineInstance.updaeTrackLine(sessionId, latlng)
    }

    // 是否更新自定义点顶部描述和接地线
    if (!showOverlay) return false
    let cssText = ''
    let _latlng = [...latlng]
    _latlng[2] = latlng[2] + 100
    if (style) cssText = CSS_TEXT + 'background:' + style.fillColor
    this.popupOverlayInstance.updatePopupOverlay('label_' + sessionId, _latlng, popupData, cssText)
    this.updateClampToGroundLine(sessionId, latlng, _latlng)
  }

  /**
   * @desc: 删除自定义点
   * @param {Number} sessionId
   * @return {*}
   * @use: 使用示例
   */
  delCustomPoint (sessionId) {
    let hasCurrentPoint = this.pointHashMap.has(sessionId)
    if (!hasCurrentPoint) return false

    let currentPoint = this.pointHashMap.get(sessionId).item2d
    if (currentPoint) {
      let feature = currentPoint.feature
      let radius = feature.getProperties()['radius']
      let type = feature.getProperties()['type']
      if (radius > 0 && type >= 5) removeFeatureAndDeleteHashMap(sessionId, this.circleHashMap, this.vectorSource, this.entities)
    }
    removeFeatureAndDeleteHashMap(sessionId, this.pointHashMap, this.vectorSource, this.entities)

    // 删除自定义点顶部描述和接地线
    this.popupOverlayInstance.delPopupOverlay('label_' + sessionId)
    this.delClampToGroundLine(sessionId)
  }

  /**
   * @desc: 获取自定义点信息
   * @param {Number} sessionId
   * @return {*}
   * @use: 使用示例
   */
  getCustomPoint (sessionId) {
    return this.pointHashMap.get(sessionId)
  }

  /**
   * @desc: 渲染circle
   * @param {Number} sessionId
   * @param {Array} latlng
   * @param {Number} type 1-单线飞行和机载航线中的航点 2-指点飞行的点 3-自定义点 4-吊舱视野位置区域 5-禁飞区 6-电子围栏
   * @param {Number} isHover
   * @param {Number} radius
   * @param {Object} style
   * @param {Number} rend3d
   */
  addCustomPointCircle (sessionId, latlng, radius, style, rend3d) {
    let circle = new Circle(this.ol2d, this.vectorSource)
    circle.addCircle2(sessionId, latlng, 3, 1, radius, style, rend3d)

    let position = new Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1], latlng[2] || 80)
    let circle3d = new Circle3d(this.entities, 'customPointCircle3d_' + sessionId, 3, latlng, radius, null)
    circle3d.position = position

    this.circleHashMap.set(sessionId, { 'item2d': circle, 'item3d': circle3d })
    return sessionId
  }

  /**
   * @desc: 更新自定义点的circle
   * @param {Number} sessionId
   * @param {Array} latlng
   * @param {Number} radius
   * @param {Object} style
   */
  updateCustomPointCircle (sessionId, latlng, radius, style) {
    let currentCircle = this.circleHashMap.get(sessionId).item2d
    currentCircle.updateCircle2(sessionId, latlng, 3, 1, radius, style, false, this.circleHashMap)
  }

  /**
   * @desc: 接地的线（只在3d上显示）
   * @param {Number} sessionId
   * @param {Array} currentLatlng
   * @param {Array} nextLatlng
   */
  addClampToGroundLine (sessionId, currentLatlng, nextLatlng, style) {
    if (currentLatlng[0] == 0 || currentLatlng[1] == 0 || nextLatlng[0] == 0 || nextLatlng[1] == 0) return false

    let positions = []
    positions[0] = new Cesium.Cartesian3.fromDegrees(currentLatlng[0], currentLatlng[1], currentLatlng[2])
    positions[1] = new Cesium.Cartesian3.fromDegrees(nextLatlng[0], nextLatlng[1], nextLatlng[2])
    let line3d = new Line3d(this.entities, 'clampToGroundLine_' + sessionId, style, true, false)
    line3d.positions = positions

    this.clampToGroundLineHashMap.set(sessionId, { 'item2d': null, 'item3d': line3d })
  }

  /**
   * @desc: 删除消防员接地线
   * @param {Number} sessionId
   */
  delClampToGroundLine (sessionId) {
    let currentLine = this.clampToGroundLineHashMap.get(sessionId)
    if (!currentLine) return false

    this.entities.remove(currentLine.item3d.entity)
  }

  /**
   * @desc: 更新消防员接地线
   * @param {Number} sessionId
   * @param {Array} currentLatlng
   * @param {Array} nextLatlng
   */
  updateClampToGroundLine (sessionId, currentLatlng, nextLatlng) {
    let currentLine = this.clampToGroundLineHashMap.get(sessionId)
    if (!currentLine) return false

    // 3d （线特有的更新方式）
    let currentLine3d = currentLine.item3d
    let positions = currentLine3d.positions
    positions[0] = new Cesium.Cartesian3.fromDegrees(currentLatlng[0], currentLatlng[1], currentLatlng[2])
    positions[1] = new Cesium.Cartesian3.fromDegrees(nextLatlng[0], nextLatlng[1], nextLatlng[2])
  }

  /**
   * @desc: 更显空地协同机组相关
   * @param {Number} sessionId
   * @param {Array} latlng
   */
  updateAirGroundCooAircrew (sessionId, latlng, yaw = 0, hpr = [], showTrack = false, type) {
    let _latlng = [...latlng]
    _latlng[2] = latlng[2] + 100
    this.popupOverlayInstance.updatePopupOverlay('label_' + sessionId, _latlng)
    this.popupOverlayInstance.updatePopupOverlay('airGroundCoo_' + sessionId, latlng, '', '', yaw, hpr)
    // 固定翼显示航迹
    // if (showTrack && type == 300) this.trackLineInstance.updaeTrackLine(sessionId, latlng)
  }

  /**
   * @desc: 删除空地协同机组相关等
   * @param {Number} sessionId
   */
  delAirGroundCooAircrew (sessionId) {
    this.popupOverlayInstance.delPopupOverlay('label_' + sessionId)
    this.popupOverlayInstance.delPopupOverlay('airGroundCoo_' + sessionId)
  }
}

export default CustomPoint
